home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 September / PCWSEP07.iso / Software / Linux / Linux Mint 3.0 Light / LinuxMint-3.0-Light.iso / casper / filesystem.squashfs / usr / share / gettext / intl / printf.c < prev    next >
Encoding:
C/C++ Source or Header  |  2007-03-05  |  8.9 KB  |  423 lines

  1. /* Formatted output to strings, using POSIX/XSI format strings with positions.
  2.    Copyright (C) 2003, 2006 Free Software Foundation, Inc.
  3.    Written by Bruno Haible <bruno@clisp.org>, 2003.
  4.  
  5.    This program is free software; you can redistribute it and/or modify it
  6.    under the terms of the GNU Library General Public License as published
  7.    by the Free Software Foundation; either version 2, or (at your option)
  8.    any later version.
  9.  
  10.    This program is distributed in the hope that it will be useful,
  11.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.    Library General Public License for more details.
  14.  
  15.    You should have received a copy of the GNU Library General Public
  16.    License along with this program; if not, write to the Free Software
  17.    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
  18.    USA.  */
  19.  
  20. #ifdef HAVE_CONFIG_H
  21. # include <config.h>
  22. #endif
  23.  
  24. #ifdef __GNUC__
  25. # define alloca __builtin_alloca
  26. # define HAVE_ALLOCA 1
  27. #else
  28. # ifdef _MSC_VER
  29. #  include <malloc.h>
  30. #  define alloca _alloca
  31. # else
  32. #  if defined HAVE_ALLOCA_H || defined _LIBC
  33. #   include <alloca.h>
  34. #  else
  35. #   ifdef _AIX
  36.  #pragma alloca
  37. #   else
  38. #    ifndef alloca
  39. char *alloca ();
  40. #    endif
  41. #   endif
  42. #  endif
  43. # endif
  44. #endif
  45.  
  46. #include <stdio.h>
  47.  
  48. #if !HAVE_POSIX_PRINTF
  49.  
  50. #include <errno.h>
  51. #include <limits.h>
  52. #include <stdlib.h>
  53. #include <string.h>
  54.  
  55. /* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW.  */
  56. #ifndef EOVERFLOW
  57. # define EOVERFLOW E2BIG
  58. #endif
  59.  
  60. /* When building a DLL, we must export some functions.  Note that because
  61.    the functions are only defined for binary backward compatibility, we
  62.    don't need to use __declspec(dllimport) in any case.  */
  63. #if defined _MSC_VER && BUILDING_DLL
  64. # define DLL_EXPORTED __declspec(dllexport)
  65. #else
  66. # define DLL_EXPORTED
  67. #endif
  68.  
  69. #define STATIC static
  70.  
  71. /* This needs to be consistent with libgnuintl.h.in.  */
  72. #if defined __NetBSD__ || defined __CYGWIN__ || defined __MINGW32__
  73. /* Don't break __attribute__((format(printf,M,N))).
  74.    This redefinition is only possible because the libc in NetBSD, Cygwin,
  75.    mingw does not have a function __printf__.  */
  76. # define libintl_printf __printf__
  77. #endif
  78.  
  79. /* Define auxiliary functions declared in "printf-args.h".  */
  80. #include "printf-args.c"
  81.  
  82. /* Define auxiliary functions declared in "printf-parse.h".  */
  83. #include "printf-parse.c"
  84.  
  85. /* Define functions declared in "vasnprintf.h".  */
  86. #define vasnprintf libintl_vasnprintf
  87. #include "vasnprintf.c"
  88. #if 0 /* not needed */
  89. #define asnprintf libintl_asnprintf
  90. #include "asnprintf.c"
  91. #endif
  92.  
  93. DLL_EXPORTED
  94. int
  95. libintl_vfprintf (FILE *stream, const char *format, va_list args)
  96. {
  97.   if (strchr (format, '$') == NULL)
  98.     return vfprintf (stream, format, args);
  99.   else
  100.     {
  101.       size_t length;
  102.       char *result = libintl_vasnprintf (NULL, &length, format, args);
  103.       int retval = -1;
  104.       if (result != NULL)
  105.     {
  106.       size_t written = fwrite (result, 1, length, stream);
  107.       free (result);
  108.       if (written == length)
  109.         {
  110.           if (length > INT_MAX)
  111.         errno = EOVERFLOW;
  112.           else
  113.         retval = length;
  114.         }
  115.     }
  116.       return retval;
  117.     }
  118. }
  119.  
  120. DLL_EXPORTED
  121. int
  122. libintl_fprintf (FILE *stream, const char *format, ...)
  123. {
  124.   va_list args;
  125.   int retval;
  126.  
  127.   va_start (args, format);
  128.   retval = libintl_vfprintf (stream, format, args);
  129.   va_end (args);
  130.   return retval;
  131. }
  132.  
  133. DLL_EXPORTED
  134. int
  135. libintl_vprintf (const char *format, va_list args)
  136. {
  137.   return libintl_vfprintf (stdout, format, args);
  138. }
  139.  
  140. DLL_EXPORTED
  141. int
  142. libintl_printf (const char *format, ...)
  143. {
  144.   va_list args;
  145.   int retval;
  146.  
  147.   va_start (args, format);
  148.   retval = libintl_vprintf (format, args);
  149.   va_end (args);
  150.   return retval;
  151. }
  152.  
  153. DLL_EXPORTED
  154. int
  155. libintl_vsprintf (char *resultbuf, const char *format, va_list args)
  156. {
  157.   if (strchr (format, '$') == NULL)
  158.     return vsprintf (resultbuf, format, args);
  159.   else
  160.     {
  161.       size_t length = (size_t) ~0 / (4 * sizeof (char));
  162.       char *result = libintl_vasnprintf (resultbuf, &length, format, args);
  163.       if (result != resultbuf)
  164.     {
  165.       free (result);
  166.       return -1;
  167.     }
  168.       if (length > INT_MAX)
  169.     {
  170.       errno = EOVERFLOW;
  171.       return -1;
  172.     }
  173.       else
  174.     return length;
  175.     }
  176. }
  177.  
  178. DLL_EXPORTED
  179. int
  180. libintl_sprintf (char *resultbuf, const char *format, ...)
  181. {
  182.   va_list args;
  183.   int retval;
  184.  
  185.   va_start (args, format);
  186.   retval = libintl_vsprintf (resultbuf, format, args);
  187.   va_end (args);
  188.   return retval;
  189. }
  190.  
  191. #if HAVE_SNPRINTF
  192.  
  193. # if HAVE_DECL__SNPRINTF
  194.    /* Windows.  */
  195. #  define system_vsnprintf _vsnprintf
  196. # else
  197.    /* Unix.  */
  198. #  define system_vsnprintf vsnprintf
  199. # endif
  200.  
  201. DLL_EXPORTED
  202. int
  203. libintl_vsnprintf (char *resultbuf, size_t length, const char *format, va_list args)
  204. {
  205.   if (strchr (format, '$') == NULL)
  206.     return system_vsnprintf (resultbuf, length, format, args);
  207.   else
  208.     {
  209.       size_t maxlength = length;
  210.       char *result = libintl_vasnprintf (resultbuf, &length, format, args);
  211.       if (result != resultbuf)
  212.     {
  213.       if (maxlength > 0)
  214.         {
  215.           size_t pruned_length =
  216.         (length < maxlength ? length : maxlength - 1);
  217.           memcpy (resultbuf, result, pruned_length);
  218.           resultbuf[pruned_length] = '\0';
  219.         }
  220.       free (result);
  221.     }
  222.       if (length > INT_MAX)
  223.     {
  224.       errno = EOVERFLOW;
  225.       return -1;
  226.     }
  227.       else
  228.     return length;
  229.     }
  230. }
  231.  
  232. DLL_EXPORTED
  233. int
  234. libintl_snprintf (char *resultbuf, size_t length, const char *format, ...)
  235. {
  236.   va_list args;
  237.   int retval;
  238.  
  239.   va_start (args, format);
  240.   retval = libintl_vsnprintf (resultbuf, length, format, args);
  241.   va_end (args);
  242.   return retval;
  243. }
  244.  
  245. #endif
  246.  
  247. #if HAVE_ASPRINTF
  248.  
  249. DLL_EXPORTED
  250. int
  251. libintl_vasprintf (char **resultp, const char *format, va_list args)
  252. {
  253.   size_t length;
  254.   char *result = libintl_vasnprintf (NULL, &length, format, args);
  255.   if (result == NULL)
  256.     return -1;
  257.   if (length > INT_MAX)
  258.     {
  259.       free (result);
  260.       errno = EOVERFLOW;
  261.       return -1;
  262.     }
  263.   *resultp = result;
  264.   return length;
  265. }
  266.  
  267. DLL_EXPORTED
  268. int
  269. libintl_asprintf (char **resultp, const char *format, ...)
  270. {
  271.   va_list args;
  272.   int retval;
  273.  
  274.   va_start (args, format);
  275.   retval = libintl_vasprintf (resultp, format, args);
  276.   va_end (args);
  277.   return retval;
  278. }
  279.  
  280. #endif
  281.  
  282. #if HAVE_FWPRINTF
  283.  
  284. #include <wchar.h>
  285.  
  286. #define WIDE_CHAR_VERSION 1
  287.  
  288. /* Define auxiliary functions declared in "wprintf-parse.h".  */
  289. #include "printf-parse.c"
  290.  
  291. /* Define functions declared in "vasnprintf.h".  */
  292. #define vasnwprintf libintl_vasnwprintf
  293. #include "vasnprintf.c"
  294. #if 0 /* not needed */
  295. #define asnwprintf libintl_asnwprintf
  296. #include "asnprintf.c"
  297. #endif
  298.  
  299. # if HAVE_DECL__SNWPRINTF
  300.    /* Windows.  */
  301. #  define system_vswprintf _vsnwprintf
  302. # else
  303.    /* Unix.  */
  304. #  define system_vswprintf vswprintf
  305. # endif
  306.  
  307. DLL_EXPORTED
  308. int
  309. libintl_vfwprintf (FILE *stream, const wchar_t *format, va_list args)
  310. {
  311.   if (wcschr (format, '$') == NULL)
  312.     return vfwprintf (stream, format, args);
  313.   else
  314.     {
  315.       size_t length;
  316.       wchar_t *result = libintl_vasnwprintf (NULL, &length, format, args);
  317.       int retval = -1;
  318.       if (result != NULL)
  319.     {
  320.       size_t i;
  321.       for (i = 0; i < length; i++)
  322.         if (fputwc (result[i], stream) == WEOF)
  323.           break;
  324.       free (result);
  325.       if (i == length)
  326.         {
  327.           if (length > INT_MAX)
  328.         errno = EOVERFLOW;
  329.           else
  330.         retval = length;
  331.         }
  332.     }
  333.       return retval;
  334.     }
  335. }
  336.  
  337. DLL_EXPORTED
  338. int
  339. libintl_fwprintf (FILE *stream, const wchar_t *format, ...)
  340. {
  341.   va_list args;
  342.   int retval;
  343.  
  344.   va_start (args, format);
  345.   retval = libintl_vfwprintf (stream, format, args);
  346.   va_end (args);
  347.   return retval;
  348. }
  349.  
  350. DLL_EXPORTED
  351. int
  352. libintl_vwprintf (const wchar_t *format, va_list args)
  353. {
  354.   return libintl_vfwprintf (stdout, format, args);
  355. }
  356.  
  357. DLL_EXPORTED
  358. int
  359. libintl_wprintf (const wchar_t *format, ...)
  360. {
  361.   va_list args;
  362.   int retval;
  363.  
  364.   va_start (args, format);
  365.   retval = libintl_vwprintf (format, args);
  366.   va_end (args);
  367.   return retval;
  368. }
  369.  
  370. DLL_EXPORTED
  371. int
  372. libintl_vswprintf (wchar_t *resultbuf, size_t length, const wchar_t *format, va_list args)
  373. {
  374.   if (wcschr (format, '$') == NULL)
  375.     return system_vswprintf (resultbuf, length, format, args);
  376.   else
  377.     {
  378.       size_t maxlength = length;
  379.       wchar_t *result = libintl_vasnwprintf (resultbuf, &length, format, args);
  380.       if (result != resultbuf)
  381.     {
  382.       if (maxlength > 0)
  383.         {
  384.           size_t pruned_length =
  385.         (length < maxlength ? length : maxlength - 1);
  386.           memcpy (resultbuf, result, pruned_length * sizeof (wchar_t));
  387.           resultbuf[pruned_length] = 0;
  388.         }
  389.       free (result);
  390.       /* Unlike vsnprintf, which has to return the number of character that
  391.          would have been produced if the resultbuf had been sufficiently
  392.          large, the vswprintf function has to return a negative value if
  393.          the resultbuf was not sufficiently large.  */
  394.       if (length >= maxlength)
  395.         return -1;
  396.     }
  397.       if (length > INT_MAX)
  398.     {
  399.       errno = EOVERFLOW;
  400.       return -1;
  401.     }
  402.       else
  403.     return length;
  404.     }
  405. }
  406.  
  407. DLL_EXPORTED
  408. int
  409. libintl_swprintf (wchar_t *resultbuf, size_t length, const wchar_t *format, ...)
  410. {
  411.   va_list args;
  412.   int retval;
  413.  
  414.   va_start (args, format);
  415.   retval = libintl_vswprintf (resultbuf, length, format, args);
  416.   va_end (args);
  417.   return retval;
  418. }
  419.  
  420. #endif
  421.  
  422. #endif
  423.